<template>
	<div id="terminal-container">
		<div id="terminal-card">
			<div id="terminal" ref="terminalEl"></div>
			<!-- 固定在底部的输入框 -->
			<div v-if="showInputBox" class="input-wrapper">
				<input
					type="text"
					v-model="inputValue"
					@keydown.enter="sendInput"
					@keydown.up="navigateHistory('up')"
					@keydown.down="navigateHistory('down')"
					placeholder="输入命令并按回车发送..."
					class="terminal-input"
					ref="inputEl"
				/>
				<el-button type="primary" @click="sendInput">发送</el-button>
			</div>
		</div>

		<!-- 左侧工具面板 -->
		<div class="sidebar">
			<div class="toolbar">
				<button
					@click="toggleInputBox"
					class="toolbar-btn"
					:title="showInputBox ? '隐藏输入框' : '显示输入框'"
				>
					{{ showInputBox ? '隐藏输入' : '显示输入' }}
				</button>
				<button
					v-if="showFullscreenBtn"
					@click="toggleFullscreen"
					class="toolbar-btn"
					:title="isFullscreen ? '退出全屏' : '全屏'"
				>
					{{ isFullscreen ? '退出全屏' : '全屏' }}
				</button>
			</div>

			<!-- 命令历史面板 -->
			<div class="history-panel">
				<h3>命令历史</h3>
				<ul class="history-list">
					<li
						v-for="(cmd, index) in commandHistory"
						:key="index"
						class="history-item"
					>
						<span
							@click="executeHistoryCommand(cmd)"
							class="history-command"
						>
							{{ cmd }}
						</span>
						<button
							@click="removeHistoryCommand(index)"
							class="delete-btn"
							:title="`删除命令: ${cmd}`"
						>
							×
						</button>
					</li>
				</ul>
				<button
					v-if="commandHistory.length > 0"
					@click="clearHistory"
					class="clear-btn"
				>
					清空历史
				</button>
			</div>
		</div>
	</div>
</template>

<script setup lang="ts">
import { useRoute } from 'vue-router';
import { ref, onMounted, onUnmounted, nextTick, watch } from "vue";
import { Terminal } from "xterm";
import { FitAddon } from 'xterm-addon-fit';
import { WebglAddon } from "xterm-addon-webgl";
import "xterm/css/xterm.css";

const DEFAULT_SCROLL_BACK = 1000;
const MAX_HISTORY = 50; // 最大历史记录数量

// Refs
const terminalEl = ref<HTMLElement>();
const inputEl = ref<HTMLInputElement>();
const ws = ref<WebSocket>();
const intervalReadKey = ref(-1);
const isFullscreen = ref(false);
const showFullscreenBtn = ref(true);
const inputValue = ref('');
const showInputBox = ref(true);
const commandHistory = ref<string[]>([]);
const historyIndex = ref(-1); // 当前在历史记录中的位置

// Xterm Instances
const fitAddon = new FitAddon();
const webglAddon = new WebglAddon();
const term = new Terminal({
	allowProposedApi: true,
	fontSize: 14,
	fontFamily: 'Consolas, "Courier New", monospace',
	theme: {
		background: '#1e1e1e'
	},
	scrollback: DEFAULT_SCROLL_BACK,
	scrollOnUserInput: true, // 启用用户输入时的滚动
});

const route = useRoute();
const agentId = atob(decodeURIComponent(route.query.agentId));
const clientConnectHost = atob(decodeURIComponent(route.query.clientConnectHost));
const clientConnectTunnelPort = atob(decodeURIComponent(route.query.clientConnectTunnelPort));

// 监听输入框变化，重置历史索引
watch(inputValue, () => {
	if (historyIndex.value !== -1) {
		historyIndex.value = -1;
	}
});

// Init
onMounted(() => {
	initTerminal();
	window.addEventListener('resize', handleResize);
	setTimeout(handleResize, 100);

	// 尝试从localStorage加载历史记录
	loadHistoryFromStorage();

	// 监听WebSocket消息，提取命令
	const originalOnMessage = ws.value?.onmessage;
	ws.value.onmessage = (event: MessageEvent) => {
		if (event.type === 'message') {
			term.write(event.data);

			// 提取并记录命令（如果消息包含用户输入的命令）
			if (typeof event.data === 'string') {
				// 这里可以根据实际情况调整命令识别逻辑
				// 示例：如果消息包含用户输入提示符（如$或#），则记录为命令
				const lines = event.data.split('\n');
				for (const line of lines) {
					// 简单识别命令：如果行以提示符结尾，且不是纯输出
					if (line.trim().endsWith('$ ') || line.trim().endsWith('# ')) {
						const command = line.replace(/\s*[$#]\s*$/, '').trim();
						if (command && !commandHistory.value.includes(command)) {
							commandHistory.value.unshift(command);
							if (commandHistory.value.length > MAX_HISTORY) {
								commandHistory.value = commandHistory.value.slice(0, MAX_HISTORY);
							}
							saveHistoryToStorage();
						}
					}
				}
			}
		}
	};
});

onUnmounted(() => {
	disposeTerminal();
	window.removeEventListener('resize', handleResize);
});

// Core Functions
const initTerminal = async () => {
	if (!terminalEl.value) return;

	try {
		term.loadAddon(fitAddon);
		term.loadAddon(webglAddon);
	} catch (e) {
		console.warn('WebGL addon load failed:', e);
	}

	term.open(terminalEl.value);
	handleResize();

	// 启用终端滚动功能
	term.options.scrollOnUserInput = true;
	term.options.scrollback = DEFAULT_SCROLL_BACK;

	term.onData(data => {
		// 记录从终端输入的命令
		if (data.includes('\n') || data.includes('\r')) {
			// 提取命令并添加到历史记录
			const command = data.replace(/[\r\n]+/g, '');
			if (command && !commandHistory.value.includes(command)) {
				commandHistory.value.unshift(command);
				if (commandHistory.value.length > MAX_HISTORY) {
					commandHistory.value = commandHistory.value.slice(0, MAX_HISTORY);
				}
				saveHistoryToStorage();
			}
		}

		ws.value?.send(JSON.stringify({ action: 'read', data }));
	});

	initWebSocket();
};

const handleResize = () => {
	requestAnimationFrame(() => {
		try {
			//fitAddon.fit(); // 优先使用fitAddon自动适配
			const { cols, rows } = getSafeDimensions();
			term.resize(cols + 50, rows);

			// 强制重新计算布局
			setTimeout(() => {
				fitAddon.fit();
			}, 100);
		} catch (e) {
			console.error('FitAddon fit error:', e);
			// 降级处理
			const { cols, rows } = getSafeDimensions();
			term.resize(cols, rows);
		}
	});
};

const getSafeDimensions = () => {
	if (!terminalEl.value) return { cols: 80, rows: 24 };

	// 获取终端容器的尺寸
	const container = document.getElementById('terminal-card');
	if (!container) return { cols: 80, rows: 24 };

	// 计算可用高度（减去输入框的高度，如果显示的话）
	let availableHeight = container.clientHeight;
	if (showInputBox.value) {
		availableHeight -= 40; // 输入框高度（包含边距和边框）
	}

	// 减去侧边栏宽度
	const sidebarWidth = showInputBox.value ? 250 : 200;
	const availableWidth = container.clientWidth - sidebarWidth;

	console.log('getSafeDimensions', availableWidth, availableHeight);

	// 🔥 动态获取字符宽度（需确保 term 已初始化）
	let charWidth = 9;
	let charHeight = 17;
	if (term && term._core && term._core._renderService) {
		charWidth = term._core._renderService.dimensions.actualCellWidth || 9;
		charHeight = term._core._renderService.dimensions.actualCellHeight || 17;
	}

	// 确保至少有最小尺寸
	const minCols = 10;
	const minRows = 5;

	const cols = Math.max(minCols, Math.floor(availableWidth / charWidth));
	const rows = Math.max(minRows, Math.floor(availableHeight / charHeight));

	return { cols, rows };
};

const initWebSocket = () => {
	const wsUrl = `ws://${clientConnectHost}:${clientConnectTunnelPort}/ws?method=connectArthas&id=${agentId}`;
	console.log(wsUrl);

	ws.value = new WebSocket(wsUrl);

	ws.value.onerror = (error) => {
		console.error('WebSocket error:', error);
		term.write('\r\n[连接错误]\r\n');
		ws.value?.close();
		ws.value = undefined;
	};

	ws.value.onopen = () => {
		const { cols, rows } = getTerminalSize();
		ws.value?.send(JSON.stringify({ action: 'resize', cols, rows }));
		term.write('\x1B[1;32m[连接已建立] \x1B[0m\r\n');

		intervalReadKey.value = window.setInterval(() => {
			if (ws.value?.readyState === 1) {
				ws.value.send(JSON.stringify({ action: 'read', data: "" }));
			}
		}, 30000);
	};

	ws.value.onmessage = (event: MessageEvent) => {
		if (event.type === 'message') {
			term.write(event.data);
		}
	};

	ws.value.onclose = (event) => {
		console.log('WebSocket connection closed:', event);
		term.write('\x1B[1;31m[连接已断开] \x1B[0m\r\n');
		if (intervalReadKey.value !== -1) {
			window.clearInterval(intervalReadKey.value);
			intervalReadKey.value = -1;
		}
	};
};

const getTerminalSize = () => {
	return {
		cols: term.cols || 80,
		rows: term.rows || 24
	};
};

const toggleFullscreen = () => {
	const container = document.getElementById('terminal-container');
	if (!document.fullscreenElement && container) {
		container.requestFullscreen()
			.then(() => {
				isFullscreen.value = true;
				handleResize();
				nextTick(() => {
					if(inputEl.value) {
						inputEl.value.focus();
					}
				});
			})
			.catch(err => {
				console.error('Error attempting to enable fullscreen:', err);
			});
	} else {
		document.exitFullscreen()
			.then(() => {
				isFullscreen.value = false;
				handleResize();
				nextTick(() => {
					if(inputEl.value) {
						inputEl.value.focus();
					}
				});
			})
			.catch(err => {
				console.error('Error exiting fullscreen:', err);
			});
	}
};

const toggleInputBox = () => {
	showInputBox.value = !showInputBox.value;
	// 重新调整终端大小以适应输入框的显示/隐藏
	nextTick(() => {
		handleResize();
	});
};

const sendInput = () => {
	if (!inputValue.value.trim()) return;

	// 将输入发送到终端
	term.write(`\r${inputValue.value}\r\n`);

	// 发送到WebSocket
	ws.value?.send(JSON.stringify({ action: 'read', data: inputValue.value + '\n' }));

	// 添加到历史记录
	addToHistory(inputValue.value);

	// 清空输入框
	inputValue.value = '';
	historyIndex.value = -1;

	// 滚动到底部
	term.scrollToBottom();
};

const addToHistory = (command: string) => {
	// 避免重复命令
	if (commandHistory.value.length === 0 || commandHistory.value[0] !== command) {
		commandHistory.value.unshift(command);

		// 限制历史记录数量
		if (commandHistory.value.length > MAX_HISTORY) {
			commandHistory.value = commandHistory.value.slice(0, MAX_HISTORY);
		}

		// 保存到本地存储
		saveHistoryToStorage();
	}
};

const executeHistoryCommand = (command: string) => {
	inputValue.value = command;
	if(inputEl.value) {
		inputEl.value.focus();
	}
};

const navigateHistory = (direction: 'up' | 'down') => {
	if (commandHistory.value.length === 0) return;

	if (direction === 'up') {
		// 向上导航
		if (historyIndex.value < commandHistory.value.length - 1) {
			historyIndex.value++;
			inputValue.value = commandHistory.value[historyIndex.value];
		}
	} else {
		// 向下导航
		if (historyIndex.value > 0) {
			historyIndex.value--;
			inputValue.value = commandHistory.value[historyIndex.value];
		} else if (historyIndex.value === 0) {
			historyIndex.value = -1;
			inputValue.value = '';
		}
	}
};

const removeHistoryCommand = (index: number) => {
	commandHistory.value.splice(index, 1);
	saveHistoryToStorage();
};

const clearHistory = () => {
	commandHistory.value = [];
	localStorage.removeItem(`terminalCommandHistory_${agentId}`);
};

const loadHistoryFromStorage = () => {
	try {
		const stored = localStorage.getItem(`terminalCommandHistory_${agentId}`);
		if (stored) {
			commandHistory.value = JSON.parse(stored);
		}
	} catch (e) {
		console.error('Failed to load command history from storage:', e);
	}
};

const saveHistoryToStorage = () => {
	try {
		localStorage.setItem(`terminalCommandHistory_${agentId}`, JSON.stringify(commandHistory.value));
	} catch (e) {
		console.error('Failed to save command history to storage:', e);
	}
};

const disposeTerminal = () => {
	if (intervalReadKey.value !== -1) {
		window.clearInterval(intervalReadKey.value);
	}
	ws.value?.close();
	term.dispose();
	fitAddon.dispose();
	webglAddon.dispose();
};
</script>

<style scoped>
/* 修改现有的样式 */
#terminal-container {
	position: fixed;
	top: 0;
	left: 0;
	width: 100vw;
	height: 100vh;
	padding: 5px;
	background-color: #1e1e1e;
	display: flex;
	flex-direction: row; /* 改为水平布局 */
}

#terminal-card {
	position: relative;
	flex: 1;
	min-height: 0;
	display: flex;
	flex-direction: column;
	/* 移除居中和最大宽度限制，让终端铺满容器 */
	width: 100%;
	height: 100%;
	border-radius: 0;
	overflow: hidden;
}

#terminal {
	flex: 1;
	min-height: 0;
	overflow: hidden;
	background-color: #1e1e1e;
	/* 确保终端内容铺满容器 */
	width: 100%;
	height: 100%;
}

.input-wrapper {
	display: flex;
	padding: 5px;
	background-color: #1e1e1e;
	border-top: 1px solid #333;
	gap: 5px;
}

.terminal-input {
	flex: 1;
	height: 30px;
	padding: 0 10px;
	background-color: #2e2e2e;
	color: white;
	border: 1px solid #444;
	border-radius: 4px 0 0 4px;
	font-family: 'Consolas', 'Courier New', monospace;
	font-size: 14px;
	box-sizing: border-box;
}

.terminal-input:focus {
	outline: none;
	border-color: #0078d4;
}

.send-btn {
	height: 30px;
	padding: 0 15px;
	background-color: #0078d4;
	color: white;
	border: 1px solid #0078d4;
	border-radius: 0 4px 4px 0;
	cursor: pointer;
	font-size: 12px;
}

.send-btn:hover {
	background-color: #005a9e;
}

/* 左侧边栏 */
.sidebar {
	width: 360px;
	background-color: rgba(30, 30, 30, 0.9);
	border-left: 1px solid #333;
	display: flex;
	flex-direction: column;
	padding: 10px;
	color: white;
	overflow: hidden;
	box-sizing: border-box;
}

/* 工具栏 */
.toolbar {
	margin-bottom: 15px;
}

.toolbar-btn {
	display: block;
	width: 100%;
	padding: 8px 12px;
	margin-bottom: 8px;
	background-color: rgba(0, 0, 0, 0.8);
	color: white;
	border: 1px solid #444;
	border-radius: 4px;
	cursor: pointer;
	font-size: 14px;
	transition: background-color 0.2s;
	box-sizing: border-box;
}

.toolbar-btn:hover {
	background-color: rgba(0, 0, 0, 1);
}

/* 历史面板 */
.history-panel h3 {
	margin: 0 0 10px 0;
	font-size: 16px;
	color: #ccc;
	border-bottom: 1px solid #444;
	padding-bottom: 5px;
}

.history-list {
	flex: 1;
	overflow-y: auto;
	max-height: 300px;
	list-style: none;
	padding: 0;
	margin: 0;
}

.history-item {
	padding: 8px 8px;
	background-color: #2a2a2a;
	margin-bottom: 4px;
	border-radius: 3px;
	cursor: pointer;
	font-size: 14px;
	font-family: 'Consolas', 'Courier New', monospace;
	overflow: hidden;
	display: flex;
	justify-content: space-between;
	align-items: center;
}

.history-command {
	flex: 1;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
	cursor: pointer;
}

.delete-btn {
	width: 20px;
	height: 20px;
	background-color: #ff4d4f;
	color: white;
	border: none;
	border-radius: 50%;
	cursor: pointer;
	font-size: 12px;
	display: flex;
	align-items: center;
	justify-content: center;
	margin-left: 8px;
	flex-shrink: 0;
}

.delete-btn:hover {
	background-color: #f5222d;
}

.clear-btn {
	width: 100%;
	padding: 8px;
	margin-top: 10px;
	background-color: #444;
	color: white;
	border: none;
	border-radius: 4px;
	cursor: pointer;
	font-size: 14px;
}

.clear-btn:hover {
	background-color: #555;
}

/* 全屏模式下的样式调整 */
#terminal-container:-webkit-full-screen {
	padding: 0;
	border-radius: 0;
}

#terminal-container:fullscreen {
	padding: 0;
	border-radius: 0;
}
</style>



